﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
using Util;

namespace UtilEditors
{
    public class BaseEditorWindow : EditorWindow
    {
        public static GUILayoutOption[] GUIs = new GUILayoutOption[] {
         GUILayout.Width(100),
         GUILayout.Height(20),
        };

        public GUILayoutOption[] BoxLayout;
        public GUIStyle textStyle;
        public GameObject[] SelectionObj => Selection.gameObjects;

        public virtual void Awake()
        {
            Repaint();
            BoxLayout = new GUILayoutOption[] { GUILayout.MaxWidth(position.width - 200), GUILayout.MaxWidth(position.height), };
        }

        public static BaseEditorWindow rfe;

        //快捷键  把 # % & 组合使用吧。#代表Shift，%代表Ctrl，&代表Alt。
        //[MenuItem("Tools/辅助/GameWindow %&F12")]==> Ctrl + Alt + F12
        public static void Init<T>() where T : BaseEditorWindow
        {
            rfe = (T)EditorWindow.GetWindow(typeof(T));
            rfe.Show();
        }

        public virtual void OnEnable()
        {
        }

        public virtual void OnFocus()
        {
            //Debug.Log("当窗口获得焦点时调用一次");
        }

        public virtual void OnLostFocus()
        {
            // Debug.Log("当窗口丢失焦点时调用一次");
        }

        public virtual void OnHierarchyChange()
        {
            //Debug.Log("当Hierarchy视图中的任何对象发生改变时调用一次");
        }

        public virtual void OnProjectChange()
        {
            //Debug.Log("当Project视图中的资源发生改变时调用一次");
        }

        //选择其他对象
        public virtual void OnSelectionChange() { }

        // 滑动列表 可点击返回ID HoverID悬停ID,ClickID点击ID,点击返回True
        public static bool ScrollToggles(ref int HoverID, ref int ClickID, IList<KeyValuePair<int, string>> toggleDes, ref Vector2 ScrollPos, int Width, int Height)
        {
            GUIStyle textStyle = new GUIStyle("ButtonLeft");
            textStyle.alignment = TextAnchor.MiddleLeft;
            var roff = textStyle.margin;
            roff.top = 0;
            roff.bottom = 0;
            textStyle.margin = roff;

            ClickID = -1;
            int rowCount = toggleDes.Count;
            ScrollPos = GUILayout.BeginScrollView(ScrollPos, false, true, GUILayout.Width(Width), GUILayout.Height(Height));
            {
                for (int index = 0; index < rowCount; index++)
                {
                    bool flag = GUILayout.Toggle(toggleDes[index].Key == HoverID, toggleDes[index].Value, textStyle);
                    if (flag != (toggleDes[index].Key == HoverID))
                    {
                        HoverID = toggleDes[index].Key;
                        if (Event.current.type == EventType.Used)
                        {
                            ClickID = toggleDes[index].Key;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }
            GUILayout.EndScrollView();
            return false;
        }

        public static bool Button(string com)
        {
            return GUILayout.Button(com, GUIs);
        }

        public static void EnumPopup(Enum com)
        {
            EditorGUILayout.EnumPopup(com, GUIs);
        }

        public static void Toggle(string com, ref bool isTogg, bool isWidth = false)
        {
            if (isWidth)
            {
                isTogg = GUILayout.Toggle(isTogg, com, GUILayout.MaxWidth(com.Length * 4 + 20));
            }
            else
            {
                isTogg = GUILayout.Toggle(isTogg, com);
            }
        }

        public static void ToggleLeft(string com, ref bool isTogg, bool isWidth = false)
        {
            if (isWidth)
            {
                isTogg = EditorGUILayout.ToggleLeft(com, isTogg, GUILayout.MaxWidth(com.Length * 4 + 20));
            }
            else
            {
                isTogg = EditorGUILayout.ToggleLeft(com, isTogg);
            }
        }

        public static bool ToggleLeft(string com, bool isTogg, bool isWidth = false)
        {
            if (isWidth)
            {
                return EditorGUILayout.ToggleLeft(com, isTogg, GUILayout.MaxWidth(com.Length * 4 + 20));
            }
            return EditorGUILayout.ToggleLeft(com, isTogg);
        }

        //...水平布局
        public static void StrX() { GUILayout.BeginHorizontal(); }

        public static void EndX()
        {
            GUILayout.EndHorizontal();
        }

        //...垂直布局
        public static void StrY() { GUILayout.BeginVertical(); }

        public static void EndY()
        {
            GUILayout.EndVertical();
        }

        public static void ComX(Action action, params GUILayoutOption[] options)
        {
            GUILayout.BeginHorizontal();
            action.toInvoke();
            GUILayout.EndHorizontal();
        }

        public static void ComY(Action action, params GUILayoutOption[] options)
        {
            GUILayout.BeginVertical(options);
            action.toInvoke();
            GUILayout.EndVertical();
        }

        //隔间
        public static void Space(int w = 20)
        {
            EditorGUILayout.Space(w);
        }

        //检测变化
        public static void ChangeCheck(Action tf, Action Ex)
        {
            EditorGUI.BeginChangeCheck();
            tf.toInvoke();
            if (EditorGUI.EndChangeCheck())
            {
                Ex.toInvoke();
            }
        }

        public static void Text(string Com)
        {
            EditorGUILayout.LabelField(Com, GUILayout.MaxWidth(Com.Length * 13));
        }

        public static void Inpt(string Name, ref int v)
        {
            StrX();
            Text(Name);
            v = EditorGUILayout.IntField(v, GUILayout.MaxWidth(50));
            EndX();
        }

        public static void Inpt(string Name, ref float v)
        {
            StrX();
            Text(Name);
            v = EditorGUILayout.FloatField(v);
            EndX();
        }

        public static void Inpt(string Name, ref Vector3 v)
        {
            v = EditorGUILayout.Vector3Field(Name, v);
        }

        public static void Inpt(string Name, ref bool v)
        {
            StrX();
            v = GUILayout.Toggle(v, Name);
            EndX();
        }

        public static void Inpt(string Name, ref Vector2 v)
        {
            v = EditorGUILayout.Vector3Field(Name, v);
        }

        public static void Inpt(string Name, ref string v)
        {
            StrX();
            Text(Name);
            v = EditorGUILayout.TextField(v);
            EndX();
        }

        /// <summary>
        /// 获取路径
        /// </summary>
        public static void FilePanel(string title, ref string path)
        {
            //获得一个长300的框
            EditorGUILayout.LabelField("选文件夹.对象: " + title);
            EditorGUILayout.LabelField(string.Format("路径:{0}", path));

            GUILayout.BeginHorizontal();
            Rect rect = EditorGUILayout.GetControlRect(/*GUILayout.Width(position.width - 160)*/);//创建GUILayout的EditorGUI大小

            Object mObj = AssetDatabase.LoadAssetAtPath<Object>(path);
            if (mObj.isTrue())
            {
                EditorGUILayout.ObjectField(mObj, typeof(Object), true, GUILayout.MaxWidth(100));
            }
            if (GUILayout.Button("选择", GUILayout.MaxWidth(60)))
            {
                path = EditorUtility.OpenFilePanel("选择文件", "", "");
                path = path.toUintyPath();
            }
            GUILayout.EndHorizontal();

            //将上面的框作为文本输入框
            path = EditorGUI.TextField(rect, path);

            //如果鼠标正在拖拽中或拖拽结束时，并且鼠标所在位置在文本输入框内
            if ((//Event.current.type == EventType.DragUpdated ||
               Event.current.type == EventType.DragExited) &&
               rect.Contains(Event.current.mousePosition))
            {
                //改变鼠标的外表
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
                {
                    path = DragAndDrop.paths[0];
                }
            }
            else
            if ((Event.current.type == EventType.DragUpdated //||
              /*Event.current.type == EventType.DragExited*/) &&
              rect.Contains(Event.current.mousePosition))
            {
                //改变鼠标的外表
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
            }
        }

        public static void InptComponent<T>(string Name, ref T v) where T : Component
        {
            StrX();
            Text(Name);
            v = EditorGUILayout.ObjectField(v, typeof(T), true) as T;
            EndX();
        }

        public static void InptObj<T>(string Name, ref T v) where T : Object
        {
            StrX();
            Text(Name);
            v = EditorGUILayout.ObjectField(v, typeof(T), true) as T;
            EndX();
        }

        public static void InptObj<T>(ref T v) where T : Object
        {
            v = EditorGUILayout.ObjectField(v, typeof(T), true) as T;
        }

        //拖选文件夹,对象,获取文件夹下全部对象
        public static void DragSelect<T>(DragSelectData<T> data) where T : Object
        {
            DragSelect(data.title, ref data.path, ref data.All, ref data.IsFoldout);
        }

        //拖选文件夹,对象,获取文件夹下全部对象
        public static void DragSelect<T>(string title, ref string path, ref List<T> All, ref bool IsFoldout) where T : Object
        {
            for (int i = All.Count - 1; i > 0; i--)
            {
                if (!All[i])
                {
                    All.RemoveAt(i);
                }
            }
            string cpath = path;
            FilePanel(title, ref path);
            if (!path.Contains("."))
            {
                if (!path.Equals(cpath))
                {
                    UtilEditor.FindPathAllFile(path, ref All);
                }
                IsFoldout = EditorGUILayout.Foldout(IsFoldout, "折叠:" + All.Count.toString());
                if (IsFoldout)
                {
                    for (int i = 0; i < All.Count; i++)
                    {
                        GUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField((i + 1).toString() + ":", GUILayout.MaxWidth(20));
                        All[i] = EditorGUILayout.ObjectField(All[i], typeof(T), true) as T;
                        GUILayout.EndHorizontal();
                    }
                }
            }
        }
    }
}